import sys
sys.path.append("..")   #也可以这样
import time
import requests
from config import kLocUserImagesPath, kSourceVideosFrame, kUserSwapperFaceFrames, kFontPath
from utils.image_utils import process_user_image
from utils.video_utils import split_video_into_frames, 加水印
from loguru import logger
from utils import face_swapper_process
from utils.cloud_utils import upload_file_to_aliyun, transform_path, upload_file_to_qiniu
from tybase.tools.image_utils import url_to_md5
from tybase.tools.image_utils import delete_file_or_directory
from utils.video_utils import synthesize_video
from utils.cloud_utils import notify
# verify_face = app.tasks['insightface_celery.face_base.verify_face']  # 人脸验证的api流程
from celerytask import app

preprocess_source_images = app.tasks['celerytask.tasks.preprocess_source_images']  # 人脸验证的api流程
import os

def convert_json_data(json_data):
    """
    转换包含在线图片 URL 的 JSON 数据，下载图片并替换为本地路径。
    """
    converted_data = json_data.copy()
    converted_data["source_images"] = []

    for source_image in json_data["source_images"]:
        converted_source_image = source_image.copy()
        converted_source_image["face_image_urls"] = [
            process_user_image(url, user_images_name=kLocUserImagesPath, max_dimension=350) 
            for url in source_image["face_image_urls"]
        ]
        converted_data["source_images"].append(converted_source_image)

    return converted_data


# 视频换脸流程
def 多人_视频_换脸(json_data, 帧数, 水印, oss_name="ali"):
    # 传入的数据其实是这样的:
    '''
    json_data = {
        "target_video": 视频url,  # 视频中的每一帧
        "source_images": [
            {
                # 第一张目标人脸的图片
                "index": 0,
                "face_image_urls": ["img/1698212401438.jpg","img/1698143160340.jpg"]
            },
            {
                # 第二张目标人脸的图片
                "index": 1,
                "face_image_urls": ["img/1698143160340.jpg"]
            }
        ]
        }
    '''
    
    
    try:
        item_dict = convert_json_data(json_data)["source_images"]
    except Exception as e:
        return {
            "verify_face": False,
            "ty_path": "",
            "error_message": "下载用户图片失败"
        }
    # 提取本地的视频目录
    try:
        frame_name = "frame_%04d.jpg"

        # 带有视频的分割,且分割以后把第一帧的人脸信息等提取出来
        video_loc_frame_path = split_video_into_frames(json_data["target_video"], kSourceVideosFrame=kSourceVideosFrame,
                                                       frames=帧数, frame_name=frame_name)   
        full_video_paths_list = []
        for i in os.listdir(video_loc_frame_path):
            if ".aac" not in i and ".jpg" in i:
                #看了是有正常在换脸的,但是为什么没合成?
                full_video_paths_list.append(os.path.join(video_loc_frame_path, i))
                
        first_video_path = full_video_paths_list[0]
        new_item_dict = {
            "target_image": first_video_path,
            "source_images": item_dict
        }
        # 只要有第一张图片的信息和人脸的坐标位置就可以了...但是这样又很麻烦,因为要把第一张图片的人脸信息提取出来
        # 这里是发送任务到Celery,主要是获取第一张图片的人脸配对信息,通过异步有办法直接获取到这个数据?
        face_pairs_list = preprocess_source_images.delay(new_item_dict).get(timeout=15)
        
        
        # 这个是输入的参数
    #     # 换脸的具体操作,会返回一个 output_directory_name 本地的分割图片
    #     # 执行到Celery这个要稍微换下
    
        # 主线程,开始发布很多任务
        output_directory_name = face_swapper_process.process_images_many_face(face_pairs_list, full_video_paths_list,
                                                                    f"{video_loc_frame_path}_{int(time.time())}")
        output_path = kUserSwapperFaceFrames + f"/{url_to_md5(json_data['target_video']).split('.')[0]}_{int(time.time())}.mp4"

    # except:
    #     pass
    
        # # 对视频进行合成!
        synthesize_video(image_directory=output_directory_name,
                         audio_path=video_loc_frame_path + "/audio.aac",
                         output_path=output_path,
                         frame_rate=帧数,
                         crf=22,
                         frame_name=frame_name,
                         )

        print("要不要加水印?")
        if 水印:
            加水印(output_path, fontfile_path=kFontPath)

        aliyun_file_path = transform_path(output_path)

        # # 把链接上传到阿里云,构建好完整的路径

        if oss_name == "qiniu":
            cloud_url = res_url = upload_file_to_qiniu(aliyun_file_path, output_path)
        else:
            cloud_url = upload_file_to_aliyun(
                aliyun_file_path, output_path)
            res_url = cloud_url.split('aliyuncs.com/')[-1]
            # 这里执行你的实际工作
        return {
            "video_loc_frame_path": video_loc_frame_path,
            "output_directory_name": output_directory_name,
            "output_path": output_path,
            "aliyun_file_path": cloud_url,
            "ty_path": res_url,
            "verify_face": True,
            "error_message": ""
        }


    except Exception as e:
        return {
            "video_loc_frame_path": video_loc_frame_path,
            "output_directory_name": output_directory_name,
            "output_path": output_path,
            "aliyun_file_path": cloud_url,
            "ty_path": res_url,
            "verify_face": True,
            "error_message": e[:200]
        }
    finally:
        pass
        # 这里不删除了,但是
        delete_file_or_directory(output_directory_name)
        delete_file_or_directory(output_path)
        for file in new_item_dict["source_images"]:
            for file_1 in file["face_image_urls"]:
                print (file_1)
                delete_file_or_directory(file_1)
        delete_file_or_directory(video_loc_frame_path)


if __name__ == '__main__':
    from tybase.tools.Task import TaskRunner
    
    json_data = {
        # "target_video": "http://oss.ubookapp.com/outputs/test/280_1699878326.mp4",  # 视频中的每一帧
        # "target_video": "http://usfile.chaotuapp.com/upload/sync/5f0751f17b8651101a1c0e768e23e44c.mp4",  # 视频中的每一帧
        "target_video": "https://ty-aihuanlian.oss-cn-shanghai.aliyuncs.com/test/RPReplay_Final1699878287.mov",  # 视频的路径
        "source_images": [
            {
                # 第一张目标人脸的图片
                "index": 0,
                "face_image_urls": ["http://usfile.chaotuapp.com/uploads/android/user/1699935515321.jpg"]
            },
            {
                # 第二张目标人脸的图片
                "index": 1,
                "face_image_urls": ["https://ty-aihuanlian.oss-cn-shanghai.aliyuncs.com/test/IMG_2760.jpg"]
            }
        ]
        }
    # 最终传递的
    print (多人_视频_换脸(json_data,
              帧数=15,
              水印=False
              ))
    # 创建后台任务
    # task = TaskRunner.Task(视频_换脸, {'param1': 'value1', 'param2': 'value2'}, callback=notify)
    
    

